package com.yuan.sys.modular.mould.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuan.core.consts.CommonConstant;
import com.yuan.core.enums.CommonStatusEnum;
import com.yuan.core.exception.ServiceException;
import com.yuan.core.factory.PageFactory;
import com.yuan.core.pojo.page.PageResult;
import com.yuan.core.util.PoiUtil;
import com.yuan.sys.modular.driver.enums.SysDriverExceptionEnum;
import com.yuan.sys.modular.mould.entity.SysMould;
import com.yuan.sys.modular.mould.entity.SysMouldExcelBody;
import com.yuan.sys.modular.mould.enums.SysMouldExceptionEnum;
import com.yuan.sys.modular.mould.mapper.SysMouldMapper;
import com.yuan.sys.modular.mould.param.SysMouldParam;
import com.yuan.sys.modular.mould.result.SysMouldResult;
import com.yuan.sys.modular.mould.service.SysMouldService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hongawen
 * @version 1.0.0
 * @date 2021年10月24日 21:56
 */
@Service
public class SysMouldServiceImpl extends ServiceImpl<SysMouldMapper, SysMould> implements SysMouldService {

    @Override
    public PageResult<SysMouldResult> page(SysMouldParam sysMouldParam) {
        QueryWrapper<SysMouldResult> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(sysMouldParam)) {
            //根据关键字模糊查询（模具编号）
            if (ObjectUtil.isNotEmpty(sysMouldParam.getSearchValue())) {
                queryWrapper.and(q -> q.like("sys_mould.mould_no", sysMouldParam.getSearchValue())
                );
            }
            //根据客户筛选
            if (ObjectUtil.isNotEmpty(sysMouldParam.getSearchCustomerName())) {
                queryWrapper.eq("sys_mould.customer_name", sysMouldParam.getSearchCustomerName());
            }
            //排序
            if (ObjectUtil.isAllNotEmpty(sysMouldParam.getSortBy(), sysMouldParam.getOrderBy())) {
                queryWrapper.orderBy(true, sysMouldParam.getOrderBy().equals(CommonConstant.ASC), StrUtil.toUnderlineCase(sysMouldParam.getSortBy()));
            }
        }
        queryWrapper.ne("sys_mould.status", CommonStatusEnum.DELETED.getCode());
        return new PageResult<>(this.baseMapper.page(PageFactory.defaultPage(), queryWrapper));
    }

    @Override
    public void export(SysMouldParam sysMouldParam) {
        QueryWrapper<SysMould> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("sys_mould.status", CommonStatusEnum.DELETED.getCode());
        List<SysMould> list = this.list(queryWrapper);
        PoiUtil.exportExcelWithStream("Moulds.xls", SysMould.class, list);
    }

    @Override
    public void delete(List<SysMouldParam> sysMouldParamList) {
        sysMouldParamList.forEach(sysMouldParam -> {
            SysMould sysMould = this.querySysMould(sysMouldParam);
            sysMould.setStatus(CommonStatusEnum.DELETED.getCode());
            this.updateById(sysMould);
        });
    }

    @Override
    public void edit(SysMouldParam sysMouldParam) {
        SysMould sysMould = this.querySysMould(sysMouldParam);
        checkMouldRepeated(sysMouldParam, true);
        BeanUtil.copyProperties(sysMouldParam, sysMould);
        //不能修改状态，用修改状态接口修改状态
        sysMould.setStatus(null);
        this.updateById(sysMould);
    }

    @Override
    public void add(SysMouldParam sysMouldParam) {
        checkMouldRepeated(sysMouldParam, false);
        SysMould sysMould = new SysMould();
        BeanUtil.copyProperties(sysMouldParam, sysMould);
        sysMould.setStatus(0);
        this.save(sysMould);
    }

    @Override
    public void dealExcelData(MultipartFile file, String customer) {
        List<SysMould> sysMoulds = new ArrayList<>();
        try {
            InputStream in = file.getInputStream();
            EasyExcel.read(in, SysMouldExcelBody.class, new PageReadListener<SysMouldExcelBody>(dataList -> {
                for (SysMouldExcelBody sysMouldExcelBody : dataList) {
                    SysMould sysMould = new SysMould();
                    BeanUtil.copyProperties(sysMouldExcelBody, sysMould);
                    sysMould.setCustomerName(customer);
                    sysMould.setStatus(0);
                    sysMoulds.add(sysMould);
                }
            })).sheet().doRead();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (CollectionUtils.isEmpty(sysMoulds)) {
            throw new ServiceException(SysMouldExceptionEnum.EXCEL_NO_DATA);
        }
        this.saveBatch(sysMoulds);
        new Thread(() -> {
            //进行数据检查，排查非唯一性的数据
            this.baseMapper.cleanData();
        }).start();
    }

    /**
     * 校验参数，检查是否存在重复数据
     */
    private void checkMouldRepeated(SysMouldParam sysMouldParam, boolean isExcludeSelf) {
        Long id = sysMouldParam.getId();
        LambdaQueryWrapper<SysMould> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMould::getCustomerName, sysMouldParam.getCustomerName())
                .eq(SysMould::getMouldNo, sysMouldParam.getMouldNo())
                .ne(SysMould::getStatus, CommonStatusEnum.DELETED.getCode());
        //是否排除自己，如果是则查询条件排除自己id
        if (isExcludeSelf) {
            queryWrapper.ne(SysMould::getId, id);
        }
        int countByAccount = this.count(queryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new ServiceException(SysMouldExceptionEnum.MOULD_REPEAT);
        }
    }


    /**
     * 获取模具
     */
    private SysMould querySysMould(SysMouldParam sysMouldParam) {
        SysMould sysMould = this.getById(sysMouldParam.getId());
        if (ObjectUtil.isNull(sysMould)) {
            throw new ServiceException(SysDriverExceptionEnum.DRIVER_NOT_EXIST);
        }
        return sysMould;
    }
}
